﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BaseClasses
{
    /// <summary>
    /// A single vertex inside the graph (or vertex itself).
    /// </summary>
    public class Vertex : IUniqueObject
    {
        /// <summary>
        /// Vertexes symbol. The symbol is meant to be a big single letter. 
        /// </summary>
        public string Symbol
        {
            get { return this.symbol; }
        }
        readonly string symbol;

#if false
        // TODO check if needed.....
        /// <summary>
        /// All links going in/out from the vertex.
        /// </summary>
        public ICollection<Link> Links
        {
            get { return this.links; }
            protected set { this.links = value; }
        }
        ICollection<Link> links = new List<Link>();
#endif

        /// <summary>
        /// Has the vertex been visited.
        /// </summary>
        public bool Visited
        {
            get { return this.visited; }
            set { this.visited = value; }
        }
        bool visited;


        /// <summary>
        /// The vertex previous.
        /// </summary>
        public Vertex PreviousVertex
        {
            get { return this.previousVertex; }
            set { this.previousVertex = value; }
        }
        Vertex previousVertex;

        /// <summary>
        /// Overall travel cost (path cost and 
        /// </summary>
        public int TravelCost
        {
            get { return this.travelCost; }
            set { this.travelCost = value; }
        }
        int travelCost;

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="symbol">Vertex symbol.</param>
        public Vertex(string symbol)
        {
            this.uniqueId = UniqueIdGenerator.GetUniqueId(); ;
            this.symbol = symbol;
            this.visited = false;
            this.travelCost = 0;
        }

        /// <summary>
        /// Overriden ToString method. Returns vertexes symbol.
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Convert.ToString(Symbol);
        }


        /// <summary>
        /// Looks the collection for vertex with the same symbol as given vertex has
        /// </summary>
        /// <param name="collection">Collection</param>
        /// <param name="vertex">Vertex</param>
        public static bool ContainsVertex(ICollection<Vertex> collection, Vertex vertex)
        {
            foreach (Vertex item in collection)
                if (item == vertex)
                    return true;
            return false;
        }

        #region ========== Operators ==========

        public static bool operator ==(Vertex v1, Vertex v2)
        {
            if ((object)v1 == null && (object)v2 == null)
                return true;

            if ((object)v1 == null || (object)v2 == null)
                return false;

            return v1.Symbol == v2.Symbol;
        }

        public static bool operator !=(Vertex v1, Vertex v2)
        {
            return !(v1 == v2);
        }

        public override bool Equals(object obj)
        {
            return this == (Vertex)obj;
        }


        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        #endregion

        public int UniqueId
        {
            get { return this.uniqueId; }
        }
        protected readonly int uniqueId;
    }
}
